From ea5fc348fa6143bcd9a1979db2734617de01c96c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Timm=20B=C3=A4der?= Date: Fri, 9 Aug 2019 13:32:24 +0200 Subject: [PATCH] scale: Replace format-value signal There is no reason for this to be a signal, since multiple handlers don't make sense anyway. It was also broken because the scale needs to know when a signal handler is added so it can update the value representation. Replace the signal with a set_format_value_func function which allows us to do that. Fixes #113 --- demos/widget-factory/widget-factory.c | 16 ++-- demos/widget-factory/widget-factory.ui | 2 - gtk/gtkscale.c | 108 ++++++++++++------------- gtk/gtkscale.h | 22 ++++- 4 files changed, 80 insertions(+), 68 deletions(-) diff --git a/demos/widget-factory/widget-factory.c b/demos/widget-factory/widget-factory.c index 24dfa14f2a..50bcc8c600 100644 --- a/demos/widget-factory/widget-factory.c +++ b/demos/widget-factory/widget-factory.c @@ -1603,14 +1603,14 @@ reset_icon_size (GtkWidget *iv) gtk_widget_queue_resize (iv); } -static gchar * -scale_format_value_blank (GtkScale *scale, gdouble value) +static char * +scale_format_value_blank (GtkScale *scale, double value, gpointer user_data) { return g_strdup (" "); } -static gchar * -scale_format_value (GtkScale *scale, gdouble value) +static char * +scale_format_value (GtkScale *scale, double value, gpointer user_data) { return g_strdup_printf ("%0.*f", 1, value); } @@ -1724,8 +1724,6 @@ activate (GApplication *app) gtk_builder_add_callback_symbol (builder, "increase_icon_size", (GCallback)increase_icon_size); gtk_builder_add_callback_symbol (builder, "decrease_icon_size", (GCallback)decrease_icon_size); gtk_builder_add_callback_symbol (builder, "reset_icon_size", (GCallback)reset_icon_size); - gtk_builder_add_callback_symbol (builder, "scale_format_value", (GCallback)scale_format_value); - gtk_builder_add_callback_symbol (builder, "scale_format_value_blank", (GCallback)scale_format_value_blank); gtk_builder_add_callback_symbol (builder, "osd_frame_pressed", (GCallback)osd_frame_pressed); gtk_builder_connect_signals (builder, NULL); @@ -1945,6 +1943,12 @@ activate (GApplication *app) widget = (GtkWidget *)gtk_builder_get_object (builder, "extra_info_entry"); g_timeout_add (100, (GSourceFunc)pulse_it, widget); + widget = (GtkWidget *)gtk_builder_get_object (builder, "scale3"); + gtk_scale_set_format_value_func (GTK_SCALE (widget), scale_format_value, NULL); + + widget = (GtkWidget *)gtk_builder_get_object (builder, "scale4"); + gtk_scale_set_format_value_func (GTK_SCALE (widget), scale_format_value_blank, NULL); + widget = (GtkWidget *)gtk_builder_get_object (builder, "box_for_context"); model = (GMenuModel *)gtk_builder_get_object (builder, "new_style_context_menu_model"); set_up_context_popover (widget, model); diff --git a/demos/widget-factory/widget-factory.ui b/demos/widget-factory/widget-factory.ui index c861a6f475..09639bda56 100644 --- a/demos/widget-factory/widget-factory.ui +++ b/demos/widget-factory/widget-factory.ui @@ -1019,7 +1019,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus. 75 -1 end - @@ -1033,7 +1032,6 @@ Suspendisse feugiat quam quis dolor accumsan cursus. 75 -1 start - diff --git a/gtk/gtkscale.c b/gtk/gtkscale.c index ba5b2d2130..7f8aa1e071 100644 --- a/gtk/gtkscale.c +++ b/gtk/gtkscale.c @@ -148,6 +148,9 @@ struct _GtkScalePrivate gint digits; + GtkScaleFormatValueFunc format_value_func; + gpointer format_value_func_user_data; + guint draw_value : 1; guint value_pos : 2; }; @@ -172,13 +175,8 @@ enum { LAST_PROP }; -enum { - FORMAT_VALUE, - LAST_SIGNAL -}; static GParamSpec *properties[LAST_PROP]; -static guint signals[LAST_SIGNAL]; static void gtk_scale_set_property (GObject *object, guint prop_id, @@ -264,7 +262,6 @@ update_label_request (GtkScale *scale) size = MAX (size, min); g_free (text); - text = gtk_scale_format_value (scale, highest_value); gtk_label_set_label (GTK_LABEL (priv->value_widget), text); @@ -665,42 +662,6 @@ gtk_scale_class_init (GtkScaleClass *class) class->get_layout_offsets = gtk_scale_real_get_layout_offsets; - /** - * GtkScale::format-value: - * @scale: the object which received the signal - * @value: the value to format - * - * Signal which allows you to change how the scale value is displayed. - * Connect a signal handler which returns an allocated string representing - * @value. That string will then be used to display the scale's value. - * - * If no user-provided handlers are installed, the value will be displayed on - * its own, rounded according to the value of the #GtkScale:digits property. - * - * Here's an example signal handler which displays a value 1.0 as - * with "-->1.0<--". - * |[ - * static gchar* - * format_value_callback (GtkScale *scale, - * gdouble value) - * { - * return g_strdup_printf ("-->\%0.*g<--", - * gtk_scale_get_digits (scale), value); - * } - * ]| - * - * Returns: allocated string representing @value - */ - signals[FORMAT_VALUE] = - g_signal_new (I_("format-value"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GtkScaleClass, format_value), - _gtk_single_string_accumulator, NULL, - _gtk_marshal_STRING__DOUBLE, - G_TYPE_STRING, 1, - G_TYPE_DOUBLE); - properties[PROP_DIGITS] = g_param_spec_int ("digits", P_("Digits"), @@ -1023,7 +984,7 @@ gtk_scale_new_with_range (GtkOrientation orientation, * * Note that rounding to a small number of digits can interfere with * the smooth autoscrolling that is built into #GtkScale. As an alternative, - * you can use the #GtkScale::format-value signal to format the displayed + * you can use gtk_scale_set_format_value_func() to format the displayed * value yourself. */ void @@ -1560,26 +1521,19 @@ weed_out_neg_zero (gchar *str, return str; } -/* - * Emits #GtkScale:format-value signal to format the value; - * if no user signal handlers, falls back to a default format. - * - * Returns: formatted value - */ -static gchar * +static char * gtk_scale_format_value (GtkScale *scale, - gdouble value) + double value) { - gchar *fmt = NULL; GtkScalePrivate *priv = gtk_scale_get_instance_private (scale); - g_signal_emit (scale, signals[FORMAT_VALUE], 0, value, &fmt); - - if (fmt) - return fmt; + if (priv->format_value_func) + { + return priv->format_value_func (scale, value, priv->format_value_func_user_data); + } else { - fmt = g_strdup_printf ("%0.*f", priv->digits, value); + char *fmt = g_strdup_printf ("%0.*f", priv->digits, value); return weed_out_neg_zero (fmt, priv->digits); } } @@ -2075,3 +2029,43 @@ gtk_scale_buildable_custom_finished (GtkBuildable *buildable, } } + +/** + * gtk_scale_set_format_value_func: + * @scale: a #GtkScale + * @func: (nullable): function that formats the value + * @user_data: (nullable): user data to pass to @func + * + * @func allows you to change how the scale value is displayed. The given + * function will return an allocated string representing @value. + * That string will then be used to display the scale's value. + * + * If #NULL is passed as @func, the value will be displayed on + * its own, rounded according to the value of the #GtkScale:digits property. + */ +void +gtk_scale_set_format_value_func (GtkScale *scale, + GtkScaleFormatValueFunc func, + gpointer user_data) +{ + GtkScalePrivate *priv = gtk_scale_get_instance_private (scale); + GtkAdjustment *adjustment; + char *text; + + g_return_if_fail (GTK_IS_SCALE (scale)); + + priv->format_value_func = func; + priv->format_value_func_user_data = user_data; + + if (!priv->value_widget) + return; + + update_label_request (scale); + + adjustment = gtk_range_get_adjustment (GTK_RANGE (scale)); + text = gtk_scale_format_value (scale, + gtk_adjustment_get_value (adjustment)); + gtk_label_set_label (GTK_LABEL (priv->value_widget), text); + + g_free (text); +} diff --git a/gtk/gtkscale.h b/gtk/gtkscale.h index a76cd81f53..c18a82ecff 100644 --- a/gtk/gtkscale.h +++ b/gtk/gtkscale.h @@ -55,9 +55,6 @@ struct _GtkScaleClass { GtkRangeClass parent_class; - gchar* (* format_value) (GtkScale *scale, - gdouble value); - void (* get_layout_offsets) (GtkScale *scale, gint *x, gint *y); @@ -67,6 +64,21 @@ struct _GtkScaleClass gpointer padding[8]; }; + +/** + * GtkScaleFormatValueFunc: + * @scale: The #GtkScale + * @value: The numeric value to format + * @user_data: (closure): user data + * + * Returns: (not nullable): A newly allocated string describing a textual representation + * of the given numerical value. + */ +typedef char * (*GtkScaleFormatValueFunc) (GtkScale *scale, + double value, + gpointer user_data); + + GDK_AVAILABLE_IN_ALL GType gtk_scale_get_type (void) G_GNUC_CONST; GDK_AVAILABLE_IN_ALL @@ -113,6 +125,10 @@ void gtk_scale_add_mark (GtkScale *scale, GDK_AVAILABLE_IN_ALL void gtk_scale_clear_marks (GtkScale *scale); +GDK_AVAILABLE_IN_ALL +void gtk_scale_set_format_value_func (GtkScale *scale, + GtkScaleFormatValueFunc func, + gpointer user_data); G_END_DECLS -- 2.30.2